﻿#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<stddef.h>

#pragma pack(show)//8
struct A
{
	char a;//0
	int b;//4-7
};
struct B
{
	int a;
	double b;
};
struct C
{
	char a;
	int b;
	struct B bd;
};
//13.第一个元素的偏移量为0；
//14.从第二个元素开始计算偏移量；最终大小，必须是最大字节数8的倍数；
struct StudentOff //24
{
	int a;//4		0-3
	char b;//1		4-7
	double c;//8	8-15
	float d;//4		16-19
};
void testConstructOffset()
{
	//8.由于内存对齐，结构体变量sa的成员b，相对于结构体首地址，偏移量就是4个字节；
	struct A sa = { 'c',20 };
	printf("1.输出结构体变量sa的首地址：%d\n", &sa);//10221860
	printf("2.转成char*类型输出sa的首地址：%d\n", (char*)&sa);//10221860
	printf("3.输出sa的成员b偏移量：%d\n", offsetof(struct A, b));//4
	printf("4.输出sa的成员b地址：%d\n", (char*)&sa + offsetof(struct A, b));//10221864
	printf("5.转成int*类型输出sa的成员b地址：%d\n", (int*)((char*)&sa + offsetof(struct A, b)));//10221864
	printf("6.输出sa的成员b地址指向的值：%d\n", *(int*)((char*)&sa + offsetof(struct A, b)));//20
	printf("7.取出结构体变量sa的首地址，强转成int*类型，再加1,就是成员b的地址，再用指针取出值：%d\n", *((int*)&sa + 1));//20

	struct C c = { 'd',30,40,3.14 };
	int offbd = offsetof(struct C, bd);
	int offb = offsetof(struct B, b);

	printf("8.通过偏移量，输出结构体变量c的成员struct B的成员b的地址：%d\n", (char*)&c + offbd + offb);//8386324
	printf("10.通过偏移量和指针，取出结构体变量c的成员struct B的成员b的值：%f\n", *(double*)((char*)&c + offbd + offb));
	//3.140000
	printf("11.通过偏移量和结构体指针，取出结构体变量c的成员struct B的成员b的值：%f\n", ((struct B*)((char*)&c + offbd))->b);
	//3.140000
	printf("9.直接输出结构体变量c的成员struct B的成员b的地址：%d\n", &(c.bd.b));//8386324


	printf("12.输出结构体StudentOff的内存大小：%d\n", sizeof(struct StudentOff));//24
}

//main210：结构体偏移量
int main210()
{
	testConstructOffset();

	system("pause");
	return EXIT_SUCCESS;
}